"""
基于 CrewAI 的股票分析智能体基类
"""
from crewai import Agent
from langchain_openai import ChatOpenAI
import json
from abc import ABC, abstractmethod
from colorama import Fore, Style
from typing import Dict, Any, List, Optional
from pydantic import BaseModel, Field
import os
import sys


class AgentConfig(BaseModel):
    """智能体配置模型"""
    name: str = Field(description="智能体名称")
    role: str = Field(description="智能体角色")
    goal: str = Field(description="智能体目标")
    backstory: str = Field(description="智能体背景故事")
    model: str = Field(description="使用的模型名称")
    app_key: str = Field(description="API密钥")
    base_url: str = Field(description="API基础URL")
    temperature: float = Field(default=0.5, description="温度参数")
    max_tokens: int = Field(default=2000, description="最大输出长度")


class CrewAIStockAgent(ABC):
    """基于 CrewAI 的股票分析智能体基类"""
    
    def __init__(self, agent_name: str, tools: Optional[List] = None):
        self.agent_name = agent_name
        self.config = self._load_config(agent_name)
        self.llm = self._create_llm()
        self.tools = tools or []
        self.agent = self._create_agent()
        print(Fore.GREEN + f"✅ 初始化 CrewAI Agent: {self.config.name}")

    def _load_config(self, agent_name: str) -> AgentConfig:
        """加载智能体配置"""
        try:
            config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json")
            with open(config_path, "r", encoding="utf-8") as f:
                config_data = json.load(f)
                agent_config = config_data["agents"][agent_name]
                return AgentConfig(**agent_config)
        except (FileNotFoundError, json.JSONDecodeError, KeyError) as e:
            raise ValueError(f"Failed to load config for agent '{agent_name}': {e}")

    def _create_llm(self) -> ChatOpenAI:
        """创建 LLM 实例 (CrewAI 使用 LangChain 的 ChatOpenAI)"""
        return ChatOpenAI(
            model=self.config.model,
            openai_api_key=self.config.app_key,
            openai_api_base=self.config.base_url,
            temperature=self.config.temperature,
            max_tokens=self.config.max_tokens,
            request_timeout=180
        )

    def _create_agent(self) -> Agent:
        """创建 CrewAI Agent 实例"""
        return Agent(
            role=self.config.role,
            goal=self.config.goal,
            backstory=self.config.backstory,
            tools=self.tools,
            llm=self.llm,
            verbose=True,
            allow_delegation=False,
            max_iter=3
        )
    
    def get_agent(self) -> Agent:
        """获取 CrewAI Agent 实例"""
        return self.agent
    
    def get_agent_info(self) -> Dict[str, Any]:
        """获取智能体信息"""
        return {
            "name": self.config.name,
            "role": self.config.role,
            "goal": self.config.goal,
            "model": self.config.model,
            "base_url": self.config.base_url,
            "agent_type": self.__class__.__name__,
            "tools": [tool.name if hasattr(tool, 'name') else str(tool) for tool in self.tools]
        }
    
    @abstractmethod
    def create_tasks(self, **kwargs) -> List:
        """每个智能体必须实现的任务创建方法"""
        pass
